#define __W25Qxx_H_
#ifdef __W25Qxx_H_
#include "font.h"
#include "spi1.h"
#include "usart1.h"
#include "sys.h"

// W25Qxx参数
#define FLASH_CS PAout(3) // 片选
#define Flash_Chip_Select \
    while (FLASH_CS == 0) \
    {                     \
    }                     \
    FLASH_CS = 0;
#define Flash_Chip_Deselect FLASH_CS = 1                           // 取消片选
#define W25Qxx_PAGE_SIZE 256                                       // 页大小256字节
#define W25Qxx_SECTOR_SIZE 4096                                    // 扇区大小4096字节
#define W25Qxx_START_ADDR (uint32_t)0x000000                       // 起始地址
#define W25Qxx_MAX_ADDR (uint32_t)(((32 / 8) * (1024 * 1024)) - 1) // 结束地址
#define W25Qxx_BUSY 0x01                                           // 忙位
#define W25Qxx_WEL 0x02                                            // 写保护位

// spi命令
#define flash_byte_read spi1_byte_read
#define flash_byte_write spi1_byte_write
#define flash_read spi1_read
#define flash_write spi1_write

// 编程命令
#define USART_CMD_HEAD 0xABCDEF00               // 命令共有字节部分
#define ERASE_CHIP (USART_CMD_HEAD | 0x1)       // 擦除芯片
#define PROGRAM (USART_CMD_HEAD | 0x2)          // 编程
#define READDATA (USART_CMD_HEAD | 0x3)         // 读数据
#define PROGRAM_EXIT (USART_CMD_HEAD | 0x4)     // 退出编程
#define WRITE_ZK_OK_FLAG (USART_CMD_HEAD | 0x5) // 写字库已编程好的标志
#define GET_FLASH_ID (USART_CMD_HEAD | 0x06)    // 读取FLASH型号
#define YES_RE_FLASH (USART_CMD_HEAD | 0x07)    // 重新编码FLASH的应答信号

// 握手应答信号
#define START_RECEIVE_TASK 0x00 // STM32准备好接收命令
#define TASK_FINISH 0x01        // STM32命令完成
#define READ_PRAMA 0x02         // STM32准备好接收参数
#define ERROR 0x03              // STM32认为参数错误
#define START_SEND_DATA 0x04    // STM32开始输出信息
#define TASK_BUSY 0x05          // 芯片正忙
#define RE_PROGRAM_FLASH 0x06   // 重新编码FLASH
#define FLASH_BUAD 4000000

// 各种数据地址
#define USER_AREA_BASE (W25Qxx_MAX_ADDR - 1024) // 最后一K地址

// 不直接调用的函数
void spi1_dma_init(void);

// 直接调用的函数
void w25qxx_init();
void flash_w25qxx(uint32_t baud);
void flash_read_data(uint32_t addr, uint8_t *data, uint16_t size);
void flash_write_data(uint32_t addr, uint8_t *data, uint32_t size);
void flash_read_data_via_dma(uint32_t addr, uint8_t *data, uint16_t size);
#endif
